/************************************************************************/
/* CharlieCube USB:                                                     */
/* An open-source RGB LED cube firmware with USB connectivity.          */
/*                                                                      */
/* led.h                                                                */
/*                                                                      */
/* Will Robertson <aliask@gmail.com>                                    */
/*                                                                      */
/* Copyright (c) 2012 Will Robertson                                    */
/*                                                                      */
/* Permission is hereby granted, free of charge, to any person          */
/* obtaining a copy of this software and associated documentation       */
/* files (the "Software"), to deal in the Software without restriction, */
/* including without limitation the rights to use, copy, modify, merge, */
/* publish, distribute, sublicense, and/or sell copies of the Software, */
/* and to permit persons to whom the Software is furnished to do so,    */
/* subject to the following conditions:                                 */
/*                                                                      */
/* The above copyright notice and this permission notice shall be       */
/* included in all copies or substantial portions of the Software.      */
/*                                                                      */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,      */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF   */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND                */
/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS  */
/* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN   */
/* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN    */
/* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                            */
/*                                                                      */
/************************************************************************/

#ifndef __led_h_included__
#define __led_h_included__

/* A single LED state. */
struct diode {
	uchar loc;
	uchar state;
	struct diode* next;
};

/* A collection of LED states to make up a single "image" */
struct frame {
	uchar numDiodes;
	struct diode* diodes;
};

/* A collection of images that make up an animation */
struct animation {
	uchar numFrames;
	struct frame* frames;
} animation;

/* Keeps track of which frame we're up to in the animation */
static uchar framenumber;

/* Bit masks used in LED state */

#define REDLED		(1<<0)
#define GREENLED	(1<<1)
#define BLUELED		(1<<2)

/* Port and pin declarations for LED pin assignments */

#define A_PORT PORTC
#define B_PORT PORTC
#define C_PORT PORTD
#define D_PORT PORTD

#define DIRA DDRC
#define DIRB DDRC
#define DIRC DDRD
#define DIRD DDRD

#define A1_PIN 0
#define A2_PIN 1
#define A3_PIN 2
#define A4_PIN 3
#define B1_PIN 4
#define B2_PIN 5
#define B3_PIN 6
#define B4_PIN 7
#define C1_PIN 0
#define C2_PIN 1
#define C3_PIN 2
#define C4_PIN 3
#define D1_PIN 4
#define D2_PIN 5
#define D3_PIN 6
#define D4_PIN 7

/****************** LEDMAP Bit mapping ****************
	+-----+-----+-----+-----+-----+-----+-----+-----+
	|  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  |
	+-----+-----+-----+-----+-----+-----+-----+-----+
	| Cat. Port | Cath. Pin | Ano. Port | Anod. Pin |
	+-----+-----+-----+-----+-----+-----+-----+-----+
	
	Ports: 00 = A, 01 = B, 10 = C, 10 = D
	Pins:  00 = 1, 01 = 2, 10 = 3, 11 = 4
 ******************************************************/
#define A1 0
#define A2 1
#define A3 2
#define A4 3
#define B1 4
#define B2 5
#define B3 6
#define B4 7
#define C1 8
#define C2 9
#define C3 10
#define C4 11
#define D1 12
#define D2 13
#define D3 14
#define D4 15

const uchar LEDMAP[64][3] = {
	//   R             G             B               x y z    verified?
	{ (C2<<4)|(D1), (C2<<4)|(B1), (C2<<4)|(A1) }, // 0,0,0      yes
	{ (A1<<4)|(C2), (A1<<4)|(D1), (A1<<4)|(B1) }, // 0,0,1      yes
	{ (B1<<4)|(A1), (B1<<4)|(C2), (B1<<4)|(D1) }, // 0,0,2      yes
	{ (D1<<4)|(B1), (D1<<4)|(A1), (D1<<4)|(C2) }, // 0,0,3      yes
	
	{ (C3<<4)|(D2), (C3<<4)|(B1), (C3<<4)|(A2) }, // 0,1,0      yes
	{ (A2<<4)|(C3), (A2<<4)|(D2), (A2<<4)|(B1) }, // 0,1,1      yes
	{ (B1<<4)|(A2), (B1<<4)|(C3), (B1<<4)|(D2) }, // 0,1,2      yes
	{ (D2<<4)|(B1), (D2<<4)|(A2), (D2<<4)|(C3) }, // 0,1,3      yes
	
	{ (C4<<4)|(D4), (C4<<4)|(B1), (C4<<4)|(A3) }, // 0,2,0      yes
	{ (A3<<4)|(C4), (A3<<4)|(D4), (A3<<4)|(B1) }, // 0,2,1      yes
	{ (B1<<4)|(A3), (B1<<4)|(C4), (B1<<4)|(D4) }, // 0,2,2      yes
	{ (D4<<4)|(B1), (D4<<4)|(A3), (D4<<4)|(C4) }, // 0,2,3      yes

	{ (C1<<4)|(D3), (C1<<4)|(B1), (C1<<4)|(A4) }, // 0,3,0
	{ (A4<<4)|(C1), (A4<<4)|(D3), (A4<<4)|(B1) }, // 0,3,1
	{ (B1<<4)|(A4), (B1<<4)|(C1), (B1<<4)|(D3) }, // 0,3,2
	{ (D3<<4)|(B1), (D3<<4)|(A4), (D3<<4)|(C1) }, // 0,3,3

	{ (C3<<4)|(D4), (C3<<4)|(B2), (C3<<4)|(A1) }, // 1,0,0      yes
	{ (A1<<4)|(C3), (A1<<4)|(D4), (A1<<4)|(B2) }, // 1,0,1      yes
	{ (B2<<4)|(A1), (B2<<4)|(C3), (B2<<4)|(D4) }, // 1,0,2      yes
	{ (D4<<4)|(B2), (D4<<4)|(A1), (D4<<4)|(C3) }, // 1,0,3      yes

	{ (C2<<4)|(D3), (C2<<4)|(B2), (C2<<4)|(A2) }, // 1,1,0      yes
	{ (A2<<4)|(C2), (A2<<4)|(D3), (A2<<4)|(B2) }, // 1,1,1      yes
	{ (B2<<4)|(A2), (B2<<4)|(C2), (B2<<4)|(D3) }, // 1,1,2
	{ (D3<<4)|(B2), (D3<<4)|(A2), (D3<<4)|(C2) }, // 1,1,3      yes

	{ (C1<<4)|(D1), (C1<<4)|(B2), (C1<<4)|(A3) }, // 1,2,0
	{ (A3<<4)|(C1), (A3<<4)|(D1), (A3<<4)|(B2) }, // 1,2,1
	{ (B2<<4)|(A3), (B2<<4)|(C1), (B2<<4)|(D1) }, // 1,2,2      yes
	{ (D1<<4)|(B2), (D1<<4)|(A3), (D1<<4)|(C1) }, // 1,2,3      yes

	{ (C4<<4)|(D2), (C4<<4)|(B2), (C4<<4)|(A4) }, // 1,3,0      yes
	{ (A4<<4)|(C4), (A4<<4)|(D2), (A4<<4)|(B2) }, // 1,3,1      yes
	{ (B2<<4)|(A4), (B2<<4)|(C4), (B2<<4)|(D2) }, // 1,3,2      yes
	{ (D2<<4)|(B2), (D2<<4)|(A4), (D2<<4)|(C4) }, // 1,3,3      yes

	{ (C4<<4)|(D3), (C4<<4)|(B3), (C4<<4)|(A1) }, // 2,0,0
	{ (A1<<4)|(C4), (A1<<4)|(D3), (A1<<4)|(B3) }, // 2,0,1
	{ (B3<<4)|(A1), (B3<<4)|(C4), (B3<<4)|(D3) }, // 2,0,2
	{ (D3<<4)|(B3), (D3<<4)|(A1), (D3<<4)|(C4) }, // 2,0,3

	{ (C1<<4)|(D4), (C1<<4)|(B3), (C1<<4)|(A2) }, // 2,1,0
	{ (A2<<4)|(C1), (A2<<4)|(D4), (A2<<4)|(B3) }, // 2,1,1
	{ (B3<<4)|(A2), (B3<<4)|(C1), (B3<<4)|(D4) }, // 2,1,2
	{ (D4<<4)|(B3), (D4<<4)|(A2), (D4<<4)|(C1) }, // 2,1,3

	{ (C2<<4)|(D2), (C2<<4)|(B3), (C2<<4)|(A3) }, // 2,2,0
	{ (A3<<4)|(C2), (A3<<4)|(D2), (A3<<4)|(B3) }, // 2,2,1
	{ (B3<<4)|(A3), (B3<<4)|(C2), (B3<<4)|(D2) }, // 2,2,2
	{ (D2<<4)|(B3), (D2<<4)|(A3), (D2<<4)|(C2) }, // 2,2,3

	{ (C3<<4)|(D1), (C3<<4)|(B3), (C3<<4)|(A4) }, // 2,3,0
	{ (A4<<4)|(C3), (A4<<4)|(D1), (A4<<4)|(B3) }, // 2,3,1
	{ (B3<<4)|(A4), (B3<<4)|(C3), (B3<<4)|(D1) }, // 2,3,2
	{ (D1<<4)|(B3), (D1<<4)|(A4), (D1<<4)|(C3) }, // 2,3,3

	{ (C1<<4)|(D2), (C1<<4)|(B4), (C1<<4)|(A1) }, // 3,0,0
	{ (A1<<4)|(C1), (A1<<4)|(D2), (A1<<4)|(B4) }, // 3,0,1
	{ (B4<<4)|(A1), (B4<<4)|(C1), (B4<<4)|(D2) }, // 3,0,2
	{ (D2<<4)|(B4), (D2<<4)|(A1), (D2<<4)|(C1) }, // 3,0,3

	{ (C4<<4)|(D1), (C4<<4)|(B4), (C4<<4)|(A2) }, // 3,1,0
	{ (A2<<4)|(C4), (A2<<4)|(D1), (A2<<4)|(B4) }, // 3,1,1
	{ (B4<<4)|(A2), (B4<<4)|(C4), (B4<<4)|(D1) }, // 3,1,2
	{ (D1<<4)|(B4), (D1<<4)|(A2), (D1<<4)|(C4) }, // 3,1,3

	{ (C3<<4)|(D3), (C3<<4)|(B4), (C3<<4)|(A3) }, // 3,2,0
	{ (A3<<4)|(C3), (A3<<4)|(D3), (A3<<4)|(B4) }, // 3,2,1
	{ (B4<<4)|(A3), (B4<<4)|(C3), (B4<<4)|(D3) }, // 3,2,2
	{ (D3<<4)|(B4), (D3<<4)|(A3), (D3<<4)|(C3) }, // 3,2,3

	{ (C2<<4)|(D4), (C2<<4)|(B4), (C2<<4)|(A4) }, // 3,3,0
	{ (A4<<4)|(C2), (A4<<4)|(D4), (A4<<4)|(B4) }, // 3,3,1
	{ (B4<<4)|(A4), (B4<<4)|(C2), (B4<<4)|(D4) }, // 3,3,2
	{ (D4<<4)|(B4), (D4<<4)|(A4), (D4<<4)|(C2) }, // 3,3,3
};

#endif